/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package BackingBeans;

import Facebook.FacebookClientLocal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletRequest;
import smartgrid.Annotation;
import smartgrid.AnnotationInterface;
import smartgrid.Contract;
import smartgrid.Contracts;
import smartgrid.DataLine;
import smartgrid.EltricStats;
import smartgrid.EltricStatsManager;
import smartgrid.EltricStatsManagerLocal;
import smartgrid.FaceBookAccount;
import smartgrid.FacebookAccountInterface;
import smartgrid.GraphJSON;
import smartgrid.MoneyStats;
import smartgrid.Tariff;
import smartgrid.TariffInterface;
import smartgrid.TariffManager;
import smartgrid.exceptions.ContractNotExistsException;
import smartgrid.exceptions.FacebookAccountDisabledException;
import smartgrid.exceptions.NoDataAvailableException;

/**
 *
 * @author andre
 */
@ManagedBean
@SessionScoped
public class IndexBackingBean {

    private String EletricUnit;
    private String MoneyUnit;
    private String UserName;
    private Map<String, Contract> ContractsMap;
    private String SelectedContract;
    @ManagedProperty(value = "#{CurrentDate}")
    private String currentDate;
    private GregorianCalendar InitDate;
    private GregorianCalendar EndDate;
    private String Interval;
    private EltricStats CurrentEl;
    private MoneyStats CurrentMn;
    private MoneyStats CurrentMnTariff;
    private Map<String, Tariff> TariffsMap;
    private String SelectedTariff;
    private Map<String, Annotation> AnnotationsMap;
    private String SelectedAnnotation;

    /** Creates a new instance of IndexBackingBean */
    public IndexBackingBean() {

        this.InitDate = (GregorianCalendar) GregorianCalendar.getInstance();
        this.InitDate.add(GregorianCalendar.DAY_OF_YEAR, -2);

        this.EndDate = (GregorianCalendar) GregorianCalendar.getInstance();
        this.EndDate.add(GregorianCalendar.DAY_OF_YEAR, -1);

        //this.Interval = "Dia";

        this.EletricUnit = "kw";
        this.MoneyUnit = "€";

        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        FacebookClientLocal fbl = null;
        if (request != null) {
            fbl = (FacebookClientLocal) request.getSession(true).getAttribute("facebook");
            if (fbl != null) {
                this.UserName = fbl.getNome();
            }
        }


        try {
            InitialContext initCtx = new InitialContext();
            Contracts cm = (Contracts) initCtx.lookup("java:global/SmartGridEA/ContractsManager");

            FacebookAccountInterface fm = (FacebookAccountInterface) initCtx.lookup("java:global/SmartGridEA/FacebookAccountManager");

            TariffInterface tm = (TariffInterface) initCtx.lookup("java:global/SmartGridEA/TariffManager");

            FaceBookAccount fa = fm.getFacebookAccountByUID(fbl.getUId());

            List<Contract> cs = cm.getContracts(fa);

            this.ContractsMap = new TreeMap<String, Contract>();
            for (Contract c : cs) {
                this.ContractsMap.put(c.getNumber(), c);
            }
            this.SelectedContract = cs.get(0).getNumber();

            List<Tariff> ts = tm.getTariffs();

            this.TariffsMap = new TreeMap<String, Tariff>();
            for (Tariff t : ts) {
                this.TariffsMap.put(t.getName(), t);
            }

            this.SelectedTariff = cs.get(0).getTariff_CurrentTarif_role().getName();

        } catch (FacebookAccountDisabledException ex) {
            Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NamingException ex) {
            Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
        }

        this.Execute();

    }

    private List<Annotation> getAnnotationList() throws NamingException, FacebookAccountDisabledException, ContractNotExistsException {
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        FacebookClientLocal fbl = null;
        if (request != null) {
            fbl = (FacebookClientLocal) request.getSession(true).getAttribute("facebook");
            if (fbl != null) {
                this.UserName = fbl.getNome();
            }
        }

        InitialContext initCtx = new InitialContext();
        AnnotationInterface am = (AnnotationInterface) initCtx.lookup("java:global/SmartGridEA/AnnotationManager");
        return am.getContractFacebookAccountAnnotations(fbl.getUId(), this.SelectedContract);
    }

    public String getAnnotations() {
        try {
            String re = GraphJSON.AnnotationsToJSon(this.getAnnotationList());
            System.out.println(re);
            return re;
        } catch (FacebookAccountDisabledException ex) {
            Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ContractNotExistsException ex) {
            Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NamingException ex) {
            Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        return "annotation=undefined";
    }

    public String getRender() {
        return "render";
    }

    public void setRender(String render) {
    }

    private void Execute() {
        try {
            InitialContext initCtx = new InitialContext();
            EltricStatsManagerLocal em = (EltricStatsManagerLocal) initCtx.lookup("java:global/SmartGridEA/EltricStatsManager");

            short type = 0;
            if (this.Interval == null) {
                type = EltricStatsManager.NONE;
            } else if (this.Interval.equals("Dia")) {
                type = EltricStatsManager.DAYS;
            } else if (this.Interval.equals("Mes")) {
                type = EltricStatsManager.MONTHS;
            } else if (this.Interval.equals("Semana")) {
                type = EltricStatsManager.WEEKS;
            }

            Contract c = this.ContractsMap.get(this.SelectedContract);
            if (c != null) {
                EltricStats el = em.getEletricStats(this.InitDate, this.EndDate, c, type);
                this.CurrentEl = el;
                if (el.getInterval() == EltricStatsManager.NONE) {
                    this.Interval = null;
                } else if (el.getInterval() == EltricStatsManager.DAYS) {
                    this.Interval = "Dia";
                } else if (el.getInterval() == EltricStatsManager.MONTHS) {
                    this.Interval = "Mes";
                } else if (el.getInterval() == EltricStatsManager.WEEKS) {
                    this.Interval = "Semana";
                }
                this.CurrentMn = em.getMoneyStats(this.InitDate, this.EndDate, c, type);
                System.out.println("INTERVALO ELETRIC: " + this.Interval);


            }
        } catch (NamingException ex) {
            Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoDataAvailableException ex) {
            System.out.println("NO DATA");
            this.CurrentEl = null;
            this.CurrentMn = null;
            //Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public String getInterval() {
        return Interval;
    }

    public void setInterval(String Interval) {
        //System.out.println("SET INTERVAL:" + Interval);
        //this.Interval = Interval;
    }

    public String getSelectedContract() {
        return SelectedContract;
    }

    public void setSelectedContract(String SelectedContract) {
        //System.out.println("Contract: " + SelectedContract);
        //this.SelectedContract = SelectedContract;
    }

    public Set<String> getTariffs() {
        return TariffsMap.keySet();
    }

    public void setSelectedTariff(String SelectedTariff) {
        //this.SelectedTariff = SelectedTariff;
    }

    public String getSelectedTariff() {
        return SelectedTariff;
    }

    public void setContractsMap(Map<String, Contract> ContractsMap) {
        this.ContractsMap = ContractsMap;
    }

    public Set<String> getContracts() {
        return this.ContractsMap.keySet();
    }

    public String getCurrentDate() {
        return currentDate;
    }

    public void setCurrentDate(String CurrentDate) {
        System.out.println(CurrentDate);
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        /* HACK */
        if (request.getParameter("mainForm:CurrentDate") != null) {
            this.currentDate = request.getParameter("mainForm:CurrentDate");
        } else {
            this.currentDate = CurrentDate;
        }
        /* HACK */
        if (request.getParameter("mainForm:calRadioId") != null) {
            this.Interval = request.getParameter("mainForm:calRadioId");
        }
        /* HACK */
        String source = null;
        if (request.getParameter("javax.faces.source") != null) {
            source = request.getParameter("javax.faces.source");
        }
        /* HACK */
        if (request.getParameter("mainForm:tariffSelectorSelect") != null) {
            this.SelectedTariff = request.getParameter("mainForm:tariffSelectorSelect");
        }
        /* HACK */
        if (request.getParameter("mainForm:contractSelectorMenu") != null) {
            this.SelectedContract = request.getParameter("mainForm:contractSelectorMenu");
        }

        if (source == null || !source.equals("mainForm:tariffSelectorSelect")) {
            if (this.currentDate != null && !this.currentDate.isEmpty()) {
                StringTokenizer st = new StringTokenizer(this.currentDate, ",");
                String i = st.nextToken();
                String f = st.hasMoreTokens() ? st.nextToken() : i;
                DateFormat df = new SimpleDateFormat("E MMM dd yyyy hh:mm:ss");
                try {
                    Date di = df.parse(i);
                    this.InitDate.setTime(di);
                    Date dff = df.parse(f);
                    this.EndDate.setTime(dff);


                } catch (ParseException ex) {
                    Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
                }

                // Don't Select dates from the future!
                if (this.InitDate.after(Calendar.getInstance()) || this.EndDate.after(Calendar.getInstance())) {
                    this.InitDate = (GregorianCalendar) GregorianCalendar.getInstance();
                    this.InitDate.add(GregorianCalendar.DAY_OF_YEAR, -2);

                    this.EndDate = (GregorianCalendar) GregorianCalendar.getInstance();
                    this.EndDate.add(GregorianCalendar.DAY_OF_YEAR, -1);
                }

                this.Execute();
            }
        } else {
            if (this.CurrentEl != null && this.SelectedTariff != null && this.TariffsMap != null && this.TariffsMap.containsKey(this.SelectedTariff)) {
                try {
                    InitialContext initCtx = new InitialContext();
                    EltricStatsManagerLocal em = (EltricStatsManagerLocal) initCtx.lookup("java:global/SmartGridEA/EltricStatsManager");

                    this.CurrentMnTariff = em.getMoneyPrevisions(this.TariffsMap.get(this.SelectedTariff), this.CurrentEl);


                } catch (NamingException ex) {
                    Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    public String getInitDateString() {
        return this.InitDate.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US) + " " + this.InitDate.get(Calendar.DAY_OF_MONTH) + ", " + this.InitDate.get(Calendar.YEAR);
    }

    public void setInitDateString(String value) {
    }

    public String getEletricUnit() {
        return GraphJSON.StringToJSon(this.EletricUnit, "eletricUnit");
    }

    public void setEletricUnit(String EletricUnit) {
    }

    public String getMoneyUnit() {
        return GraphJSON.StringToJSon(this.MoneyUnit, "moneyUnit");
    }

    public void setMoneyUnit(String MoneyUnit) {
    }

    public void setUserName(String name) {
    }

    public String getUserName() {
        return GraphJSON.StringToJSon(this.UserName, "userName");
    }

    public void setEletricData(String l) {
    }

    public String getEletricData() {
        try {
            List<Annotation> ans = this.getAnnotationList();
            if (this.CurrentEl != null) {
                Collection<DataLine> cl = this.CurrentEl.getDataLine_role();
                if (cl != null) {
                    if(this.Interval != null && this.Interval.equals("Dia"))
                        return GraphJSON.ListToJSon(cl, "eletricData", ans);
                    else
                        return GraphJSON.ListToJSon(cl, "eletricData", new ArrayList<Annotation>());
                } else {
                    return GraphJSON.ListToJSon(new ArrayList(), "eletricData", new ArrayList<Annotation>());
                }
            }
            return GraphJSON.ListToJSon(new ArrayList(), "eletricData", ans);
        } catch (NamingException ex) {
            return GraphJSON.ListToJSon(new ArrayList(), "eletricData", new ArrayList<Annotation>());
        } catch (FacebookAccountDisabledException ex) {
            Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
            return GraphJSON.ListToJSon(new ArrayList(), "eletricData", new ArrayList<Annotation>());
        } catch (ContractNotExistsException ex) {
            Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
            return GraphJSON.ListToJSon(new ArrayList(), "eletricData", new ArrayList<Annotation>());
        }
    }

    public void setMoneyData(String l) {
    }

    public String getMoneyData() {
        try {
            List<Annotation> ans = this.getAnnotationList();
            if (this.CurrentMn != null) {
                Collection<DataLine> cl = this.CurrentMn.getDataLine_role();
                if (cl != null) {
                    if(this.Interval != null && this.Interval.equals("Dia"))
                        return GraphJSON.ListToJSon(cl, "moneyData", ans);
                    else
                        return GraphJSON.ListToJSon(cl, "moneyData", new ArrayList<Annotation>());
                } else {
                    return GraphJSON.ListToJSon(new ArrayList(), "moneyData", new ArrayList<Annotation>());
                }
            }
            return GraphJSON.ListToJSon(new ArrayList(), "moneyData", new ArrayList<Annotation>());
        } catch (NamingException ex) {
            Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
            return GraphJSON.ListToJSon(new ArrayList(), "moneyData", new ArrayList<Annotation>());
        } catch (FacebookAccountDisabledException ex) {
            Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
            return GraphJSON.ListToJSon(new ArrayList(), "moneyData", new ArrayList<Annotation>());
        } catch (ContractNotExistsException ex) {
            Logger.getLogger(IndexBackingBean.class.getName()).log(Level.SEVERE, null, ex);
            return GraphJSON.ListToJSon(new ArrayList(), "moneyData", new ArrayList<Annotation>());
        }
    }

    public void setSecMoneyData(String l) {
    }

    public String getSecMoneyData() {
        if (this.CurrentMnTariff != null) {
            Collection<DataLine> cl = this.CurrentMnTariff.getDataLine_role();
            if (cl != null) {
                
                    return GraphJSON.ListToJSon(cl, "secMoneyData", new ArrayList<Annotation>());
            } else {
                return GraphJSON.ListToJSon(new ArrayList(), "secMoneyData", new ArrayList<Annotation>());
            }
        }
        System.out.print("ISTO N DEU NADA");
        return "secMoneyData = undefined";
    }

    public String getTotal() {
        StringBuilder sb = new StringBuilder();
        if (this.CurrentMn != null) {
            sb.append(Math.round(this.CurrentMn.getTotal()));
            //sb.append(((Double) this.CurrentMn.getTotal()).toString());
            sb.append(" €");
        }
        if (this.CurrentMnTariff != null) {
            sb.append(" (");
            sb.append(Math.round(this.CurrentMnTariff.getTotal()));
            //sb.append(((Double) this.CurrentMnTariff.getTotal()).toString());
            sb.append(" €)");
            this.CurrentMnTariff = null;
        }
        return sb.toString();
    }
}
